using NUnit.Framework;
using data.contracts;

namespace generator.tests
{
    [TestFixture]
    public class NamingRulesTests
    {
        [Test]
        public void Default_Convention() {
            Assert.That(NamingRules.ToInterfaceName("foo"), Is.EqualTo("IFoo"));
        }

        [Test]
        public void Default_Convention_with_namespace() {
            Assert.That(NamingRules.ToInterfaceName("n1.n2.board.pin"), Is.EqualTo("n1.n2.IBoard"));
        }

        [Test]
        public void Given_Typename() {
            Assert.That(NamingRules.ToInterfaceName("(IBar) foo"), Is.EqualTo("IBar"));
        }

        [Test]
        public void Given_Typename_with_namespace() {
            Assert.That(NamingRules.ToInterfaceName("(n1.n2.IBar) foo"), Is.EqualTo("n1.n2.IBar"));
        }

        [Test]
        public void Given_star_type() {
            Assert.That(NamingRules.ToInterfaceName("(IBar*) foo"), Is.EqualTo("IEnumerable<IBar>"));
        }

        [Test]
        public void Given_Typename_with_leading_blanks() {
            Assert.That(NamingRules.ToInterfaceName("   (IBar) foo"), Is.EqualTo("IBar"));
        }

        [Test]
        public void Given_Typename_with_generics_and_whitespace() {
            Assert.That(NamingRules.ToInterfaceName("(Join<string, int>) foo"), Is.EqualTo("Join<string,int>"));
        }

        [Test]
        public void Variable_name_by_convention() {
            Assert.That(NamingRules.ToVariableName("foo"), Is.EqualTo("foo"));
        }

        [Test]
        public void Variable_name_by_convention_with_leading_spaces() {
            Assert.That(NamingRules.ToVariableName("  foo"), Is.EqualTo("foo"));
        }

        [Test]
        public void Variable_name_with_given_type() {
            Assert.That(NamingRules.ToVariableName("(Join< string, int, long>) foo"), Is.EqualTo("foo"));
        }

        [Test]
        public void Special_name_detection() {
            Assert.That(NamingRules.IsSpecialName("$split1"), Is.True);
        }

        [Test]
        public void Special_name_detection_with_given_type() {
            Assert.That(NamingRules.IsSpecialName("(ISplit<Tuple<int,string>,int,string>) $split1"), Is.True);
        }

        [Test]
        public void Special_variable_name() {
            Assert.That(NamingRules.ToSpecialVariableName("$split1"), Is.EqualTo("__split1"));            
        }

        [Test]
        public void Special_variable_name_with_given_type() {
            Assert.That(NamingRules.ToSpecialVariableName("(ISplit<Tuple<int,string>,int,string>) $split1"), Is.EqualTo("__split1"));            
        }

        [Test]
        public void Implementation_for_given_type() {
            Assert.That(NamingRules.ImplementationFor(new Pin{Type = "IFoo"}), Is.EqualTo("Foo"));
        }

        [Test]
        public void Implementation_for_given_type_with_namespace() {
            Assert.That(NamingRules.ImplementationFor(new Pin { Type = "n1.n2.IFoo" }), Is.EqualTo("n1.n2.Foo"));
        }

        [Test]
        public void Implementation_for_board() {
            Assert.That(NamingRules.ImplementationFor(new Pin{Board = "foo"}), Is.EqualTo("Foo"));
        }

        [Test]
        public void Implementation_for_board_with_namespace() {
            Assert.That(NamingRules.ImplementationFor(new Pin { Board = "n1.n2.foo" }), Is.EqualTo("n1.n2.Foo"));
        }
    }
}